﻿using System;
using AutoMapper;
using IdentityServer4.AccessTokenValidation;
using IdentityServer4.Configuration;
using K9Nano.Configuration.Startup;
using K9Nano.Dependency;
using K9Nano.Events.Entity;
using K9Nano.IdentityServerCore.Data.Events;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection.Extensions;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class IdentityServerStartupExtensions
    {
        public static IIdentityServerBuilder AddK9IdentityServer<TUser, TKey>(this IServiceCollection services,
            Action<IdentityServerOptions> identitySetupAction,
            Action<MvcOptions> mvcSetupAction)
            where TUser : IdentityUser<TKey>
            where TKey : IEquatable<TKey>
        {
            services.Replace(ServiceDescriptor.Singleton<IEntityEventFilter, IdentityServerEntityEventFilter>());
            services.Replace(ServiceDescriptor.Singleton<IEntityCacheFilter, IdentityServerEntityCacheFilter>());
            services.RegisterConventionalAssembly(typeof(IdentityServerStartupExtensions).Assembly);
            
            services.AddControllers(mvcSetupAction)
                .AddApplicationPart(typeof(IdentityServerStartupExtensions).Assembly);

            var builder = services.AddIdentityServer(identitySetupAction)
                .AddAspNetIdentity<TUser>();

            return builder;
        }

        public static IIdentityServerBuilder AddK9IdentityServer<TUser, TKey>(this IServiceCollection services,
            IConfiguration identityServerConfiguration,
            Action<StartupConfiguration> appSetupAction,
            Action<IdentityServerAuthenticationOptions> identityServerAuthSetupAction,
            Action<MvcOptions> mvcSetupAction = null)
            where TUser : IdentityUser<TKey>
            where TKey : IEquatable<TKey>
        {
            services.AddK9NanoAspNetCore(appSetupAction, identityServerAuthSetupAction);

            services.Replace(ServiceDescriptor.Singleton<IEntityEventFilter, IdentityServerEntityEventFilter>());
            services.Replace(ServiceDescriptor.Singleton<IEntityCacheFilter, IdentityServerEntityCacheFilter>());
            services.RegisterConventionalAssembly(typeof(IdentityServerStartupExtensions).Assembly);

            services.AddAutoMapper(typeof(IdentityServerStartupExtensions).Assembly);

            services.AddControllers(mvcSetupAction)
                .AddApplicationPart(typeof(IdentityServerStartupExtensions).Assembly);

            var builder = services.AddIdentityServer(identityServerConfiguration)
                .AddAspNetIdentity<TUser>();

            return builder;
        }
    }
}
